package com.yilian.reflection;

/**
 * Student类 - 实现Studyable接口，用于演示反射功能
 * 
 * 这个类继承自Person类并实现Studyable接口，用于演示反射机制如何：
 * 1. 获取类的继承关系（父类信息）
 * 2. 获取类实现的接口信息
 * 3. 访问继承的字段和方法
 * 4. 分析完整的类层次结构
 * 
 * 在反射中，继承关系很重要，因为：
 * - getMethods()会返回继承的公共方法
 * - getFields()会返回继承的公共字段
 * - getSuperclass()可以获取父类信息
 * - getInterfaces()可以获取实现的接口
 * 
 * @author 练习项目
 * @version 1.0
 */
public class Student extends Person implements Studyable {
    
    // ==================== 特有字段 ====================
    
    /**
     * 学号字段
     * 这是Student类特有的字段，不会出现在父类Person中
     */
    private String studentId;
    
    /**
     * 专业字段
     * 这是Student类特有的字段，用于存储学生的专业信息
     */
    private String major;
    
    // ==================== 构造器 ====================
    
    /**
     * 默认构造函数
     * 调用父类的默认构造函数，并初始化Student特有的字段
     */
    public Student() {
        super(); // 调用父类Person的默认构造函数
        this.studentId = "未知学号";
        this.major = "未知专业";
    }
    
    /**
     * 带参数构造函数
     * 调用父类的带参数构造函数，并初始化Student特有的字段
     * 
     * @param name 姓名
     * @param age 年龄
     * @param studentId 学号
     * @param major 专业
     */
    public Student(String name, int age, String studentId, String major) {
        super(name, age); // 调用父类Person的带参数构造函数
        this.studentId = studentId;
        this.major = major;
    }
    
    // ==================== getter和setter方法 ====================
    
    /**
     * 获取学号
     * 
     * @return 学号
     */
    public String getStudentId() {
        return studentId;
    }
    
    /**
     * 设置学号
     * 
     * @param studentId 要设置的学号
     */
    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }
    
    /**
     * 获取专业
     * 
     * @return 专业
     */
    public String getMajor() {
        return major;
    }
    
    /**
     * 设置专业
     * 
     * @param major 要设置的专业
     */
    public void setMajor(String major) {
        this.major = major;
    }
    
    // ==================== 接口方法实现 ====================
    
    /**
     * 实现Studyable接口的study方法
     * 通过反射可以调用这个方法，即使它是从接口继承的
     */
    @Override
    public void study() {
        System.out.println("学生 " + getName() + " 正在学习 " + major);
    }
    
    /**
     * 实现Studyable接口的takeExam方法
     * 这个方法展示了如何通过反射调用接口实现方法
     */
    @Override
    public void takeExam() {
        System.out.println("学生 " + getName() + " 正在参加考试");
    }
    
    /**
     * 实现Studyable接口的getSubject方法
     * 
     * @return 学习科目（专业）
     */
    @Override
    public String getSubject() {
        return major;
    }
    
    // ==================== 重写方法 ====================
    
    /**
     * 重写toString方法
     * 这个方法展示了如何通过反射获取重写的方法
     * 反射可以区分继承的方法和重写的方法
     * 
     * @return 学生对象的字符串表示
     */
    @Override
    public String toString() {
        return "Student{name='" + getName() + "', age=" + getAge() + 
               ", studentId='" + studentId + "', major='" + major + "'}";
    }
} 